package com.jijs.framework.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.dom4j.DocumentException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.jijs.framework.CodeConstant;
import com.jijs.framework.dao.BaseDaoI;
import com.jijs.framework.model.Tree;
import com.jijs.framework.model.pmodel.AdeModule;
import com.jijs.framework.model.pmodel.AdeUser;
import com.jijs.framework.model.tmodel.TadeModule;
import com.jijs.framework.model.tmodel.TadeRole;
import com.jijs.framework.model.tmodel.TadeUser;
import com.jijs.framework.util.IconFontHelper;
import com.jijs.framework.util.MenuUtil;
import com.jijs.framework.util.StringUtil;

/**
 * 模块及权限管理服务类
 * 
 * @author jijs
 *
 */
@Service
public class ModuleManagerService {

	private static final Logger LOG = Logger.getLogger(ModuleManagerService.class);

	@Autowired
	private BaseDaoI<TadeModule> moduleDao;
	@Autowired
	private BaseDaoI<TadeUser> userDao;

	/**
	 * 获取指定节点下的树形列表
	 * 
	 * @param user
	 *            能够访问的用户
	 * @param pid
	 *            父节点ID
	 * @return 树形菜单，null的时候为找不到对象
	 */
	public List<Tree> treeMenu(AdeUser user, String pid, String moduleGround) {

		List<Tree> topMenus = MenuUtil.list2Tree(tree(user, moduleGround));

		for (Tree topMenu : topMenus) {

			if (topMenu.getId().equals(pid)) {
				return topMenu.getChildren();
			}
		}

		return null;
	}

	/**
	 * 获取当前用户能够访问的一级菜单
	 * 
	 * @param user
	 *            用户
	 * @return 一级菜单
	 */
	public List<Tree> topMenu(AdeUser user, String moduleGround) {

		List<Tree> topMenus = MenuUtil.list2Tree(tree(user, moduleGround));

		for (Tree topMenu : topMenus) {

			boolean hasGrandson = false;

			List<Tree> subMenus = topMenu.getChildren();

			if (subMenus != null && subMenus.size() > 0) {
				// 判断孙子节点
				for (Tree subMenu : subMenus) {

					List<Tree> grandsonMenus = subMenu.getChildren();
					if (grandsonMenus != null && grandsonMenus.size() > 0) {
						hasGrandson = true;
						break;
					}
				}
			}

			topMenu.setHasGrandson(hasGrandson);
			if (hasGrandson) {
				topMenu.setChildren(null);
			}
		}

		return topMenus;

	}

	public List<Tree> tree(AdeUser user, String moduleGround) {
		List<TadeModule> l = null;
		List<Tree> lt = new ArrayList<Tree>();

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("resourceTypeId", CodeConstant.MODULE_TYPE_MENU);// 菜单类型的"菜单"

		if (user != null) {

			StringBuffer hql = new StringBuffer();
			hql.append(" select distinct t from TadeModule t ");
			hql.append("   join fetch t.tadeRoles role ");
			hql.append("   join role.tadeUsers user ");
			hql.append("  where t.moduleType = :resourceTypeId ");
			hql.append("    and user.id = :userId ");

			// 2017年4月12日：为module增加了维度（暂时定义为前台、后台）
			hql.append("    and t.moduleGround = :moduleGround ");
			hql.append("  order by t.moduleSort");

			params.put("moduleGround", moduleGround);
			params.put("userId", user.getId());// 自查自己有权限的模块
			l = moduleDao.find(hql.toString(), params);
		} else {

			StringBuffer hql = new StringBuffer();
			hql.append(" select distinct t from TadeModule t ");
			hql.append("   where t.moduleType = :resourceTypeId ");
			// 2017年4月12日：为module增加了维度（暂时定义为前台、后台）
			hql.append("     and t.moduleGround = :moduleGround ");
			hql.append("   order by t.moduleSort ");

			params.put("moduleGround", moduleGround);

			l = moduleDao.find(hql.toString(), params);
		}

		if (l != null && l.size() > 0) {
			for (TadeModule r : l) {
				Tree easyUITree = new Tree();
				BeanUtils.copyProperties(r, easyUITree);
				if (r.getTadeModule() != null) {
					easyUITree.setPid(r.getTadeModule().getId());
				}
				easyUITree.setText(r.getModuleName());
				easyUITree.setIconCls(r.getModuleIcon());
				Map<String, Object> attr = new HashMap<String, Object>();
				attr.put("url", r.getModuleUrl());
				easyUITree.setAttributes(attr);
				lt.add(easyUITree);
			}
		}

		return lt;
	}

	/**
	 * 列出所有的模块以及权限
	 * 
	 * @param user
	 *            用户信息
	 * @return 所有的模块以及权限
	 */
	public List<Tree> treeAllType(AdeUser user) {

		List<TadeModule> tAdeModules = null;
		List<Tree> result = new ArrayList<Tree>();

		Map<String, Object> params = new HashMap<String, Object>();
		if (user != null && !user.getLoginName().equals(CodeConstant.SUPER_USER_LOGIN_NAME)) {
			params.put("userId", user.getId());// 查自己有权限的模块
			tAdeModules = moduleDao.find(
					"select distinct t from TadeModule t join fetch t.tadeRoles role join role.tadeUsers user where user.id = :userId order by t.moduleSort",
					params);
		} else {
			tAdeModules = moduleDao.find("select distinct t from TadeModule t order by t.moduleSort", params);
		}

		// 没有结果，就返回空对象
		if (tAdeModules == null || tAdeModules.size() == 0) {
			return result;
		}

		for (TadeModule r : tAdeModules) {
			Tree easyUITree = new Tree();
			BeanUtils.copyProperties(r, easyUITree);
			if (r.getTadeModule() != null) {
				easyUITree.setPid(r.getTadeModule().getId());
			}
			easyUITree.setText(r.getModuleName());
			easyUITree.setIconCls(r.getModuleIcon());
			Map<String, Object> attr = new HashMap<String, Object>();
			attr.put("url", r.getModuleUrl());
			easyUITree.setAttributes(attr);
			result.add(easyUITree);
		}

		return result;
	}

	/**
	 * 将模块列表列出。根据用户进行判断，列出所有的模块树列表
	 * 
	 * @return 模块列表
	 */
	public List<AdeModule> treeGrid(AdeUser user) {
		List<AdeModule> result = new ArrayList<AdeModule>();

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("tmoduleType", "0");// 0：系统菜单

		List<TadeModule> tadeModules = null;

		if (user != null) {
			params.put("userId", user.getId());// 自查自己有权限的模块
			tadeModules = moduleDao.find(
					"select distinct t from TadeModule t join fetch t.tadeRoles role join role.tadeUsers user where user.id = :userId and t.moduleType=:tmoduleType order by t.moduleSort",
					params);
		} else {
			tadeModules = moduleDao.find(
					"select distinct t from TadeModule t where t.moduleType=:tmoduleType  order by t.moduleSort",
					params);
		}

		if (tadeModules == null || tadeModules.size() == 0) {
			return result;
		}

		for (TadeModule t : tadeModules) {
			AdeModule r = new AdeModule();
			BeanUtils.copyProperties(t, r);
			if (t.getTadeModule() != null) {
				r.setParentModuleId(t.getTadeModule().getId());
				r.setParentModuleName(t.getTadeModule().getModuleName());
				// 给Module传递图标
				r.setModuleIcon(t.getModuleIcon());
			}

			r.setModuleType(t.getModuleType());

			// r.setModuleTypeId(t.getTadeModuleType().getId());
			// r.setModuleTypeName(t.getTadeModuleType().getName());
			if (t.getModuleIcon() != null && !t.getModuleIcon().equalsIgnoreCase("")) {
				r.setModuleIcon(t.getModuleIcon());
				r.setIconCls(t.getModuleIcon());
			}
			result.add(r);
		}

		return result;
	}

	/**
	 * 
	 * 描述: 根据用户和菜单ID获取对应的功能
	 *
	 * @param user
	 * @param pid
	 *            菜单ID
	 * @return List<Module>
	 */
	public List<AdeModule> dataGridForMenu(AdeUser user, String pid) {
		List<TadeModule> l = null;
		List<AdeModule> lr = new ArrayList<AdeModule>();

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("tmoduleType", "1");// 1：功能菜单
		params.put("pid", pid);//
		if (user != null) {
			params.put("userId", user.getId());// 自查自己有权限的模块
			l = moduleDao.find(
					"select distinct t from TadeModule t join fetch t.tadeRoles role join role.tadeUsers user where user.id = :userId and t.moduleType=:tmoduleType and t.tadeModule.id=:pid order by t.moduleSort",
					params);
		} else {
			l = moduleDao.find(
					"select distinct t from TadeModule t  where  and t.moduleType=:tmoduleType and t.tadeModule.id=:pid  order by t.moduleSort",
					params);
		}

		if (l != null && l.size() > 0) {
			for (TadeModule t : l) {
				AdeModule r = new AdeModule();
				BeanUtils.copyProperties(t, r);
				if (t.getTadeModule() != null) {
					r.setParentModuleId(t.getTadeModule().getId());
					r.setParentModuleName(t.getTadeModule().getModuleName());
				}
				// r.setModuleTypeId(t.getTadeModuleType().getId());
				// r.setModuleTypeName(t.getTadeModuleType().getName());

				r.setModuleType(t.getModuleType());
				if (t.getModuleIcon() != null && !t.getModuleIcon().equalsIgnoreCase("")) {
					r.setModuleIcon(t.getModuleIcon());
				}
				lr.add(r);
			}
		}

		return lr;
	}

	@CacheEvict(value = "adeAllPermissionListCache", allEntries = true)
	public void add(AdeModule module, AdeUser user) {
		TadeModule t = new TadeModule();
		BeanUtils.copyProperties(module, t);
		if (module.getParentModuleId() != null && !module.getParentModuleId().equalsIgnoreCase("")) {
			t.setTadeModule(moduleDao.get(TadeModule.class, module.getParentModuleId()));
		}

		t.setModuleType(module.getModuleType());

		if (StringUtil.isNotEmpty(module.getModuleIcon())) {
			t.setModuleIcon(module.getModuleIcon());
		}
		moduleDao.save(t);

		// 由于当前用户所属的角色，没有访问新添加的模块权限，所以在新添加模块的时候，将当前模块授权给当前用户的所有角色，以便添加模块后在模块列表中能够找到
		TadeUser tuser = userDao.get(TadeUser.class, user.getId());
		Set<TadeRole> roles = tuser.getTadeRoles();
		for (TadeRole r : roles) {
			r.getTadeModules().add(t);
		}
	}

	/**
	 * 删除一个菜单或者权限。
	 * 
	 * @param id
	 *            要删除对象的ID
	 * @return 错误消息，如果没有错误，返回null。
	 */
	@CacheEvict(value = "adeAllPermissionListCache", allEntries = true)
	public String delete(String id) {

		// 检查子菜单信息
		Map<String, Object> menuParams = new HashMap<String, Object>();
		menuParams.put("id", id);
		menuParams.put("moduleType", CodeConstant.MODULE_TYPE_MENU);

		List<TadeModule> t55 = moduleDao
				.find("from TadeModule t where t.tadeModule.id = :id and t.moduleType = :moduleType", menuParams);
		for (TadeModule tadeModule : t55) {
			System.out.println(tadeModule.getId());
		}

		Long menuCount = moduleDao.count(
				"select count(*) from TadeModule t where t.tadeModule.id = :id and t.moduleType = :moduleType",
				menuParams);

		if (menuCount != 0) {
			return "当前节点存在子节点，无法删除，请先删除所有子节点后，重新尝试删除操作！";
		}

		// 检查权限信息
		Map<String, Object> permissionParams = new HashMap<String, Object>();
		permissionParams.put("id", id);
		permissionParams.put("moduleType", CodeConstant.MODULE_TYPE_PERMISSION);
		Long permissionCount = moduleDao.count(
				"select count(*) from TadeModule t where t.tadeModule.id = :id and t.moduleType = :moduleType",
				permissionParams);

		if (permissionCount != 0) {
			return "当前节点存在权限信息，无法删除，请先删除所有权限信息后，重新尝试删除操作！";
		}

		// 都检查完成后开始进行删除
		TadeModule t = moduleDao.get(TadeModule.class, id);

		if (t == null) {
			return "无法找到要删除的对象，请刷新页面后重新确认！";
		}

		moduleDao.delete(t);

		return null;
	}

	@CacheEvict(value = "adeAllPermissionListCache", allEntries = true)
	public void edit(AdeModule module) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("id", module.getId());
		TadeModule t = moduleDao.get("select distinct t from TadeModule t where t.id = :id", params);
		if (t != null) {
			BeanUtils.copyProperties(module, t);

			// if (module.getModuleTypeId() != null &&
			// !module.getModuleTypeId().equalsIgnoreCase("")) {
			// t.setTadeModuleType(moduleTypeDao.get(TadeModuleType.class,
			// module.getModuleTypeId()));// 赋值模块类型
			// }

			t.setModuleType(module.getModuleType());

			if (module.getModuleIcon() != null && !module.getModuleIcon().equalsIgnoreCase("")) {
				t.setModuleIcon(module.getModuleIcon());
			}
			if (module.getParentModuleId() != null && !module.getParentModuleId().equalsIgnoreCase("")) {// 说明前台选中了上级模块
				TadeModule pt = moduleDao.get(TadeModule.class, module.getParentModuleId());
				isChildren(t, pt);// 说明要将当前模块修改到当前模块的子/孙子模块下
				t.setTadeModule(pt);
			} else {
				t.setTadeModule(null);// 前台没有选中上级模块，所以就置空
			}
		}
	}

	/**
	 * 判断是否是将当前节点修改到当前节点的子节点
	 * 
	 * @param t
	 *            当前节点
	 * @param pt
	 *            要修改到的节点
	 * @return
	 */
	private boolean isChildren(TadeModule t, TadeModule pt) {
		if (pt != null && pt.getTadeModule() != null) {
			if (pt.getTadeModule().getId().equalsIgnoreCase(t.getId())) {
				pt.setTadeModule(null);
				return true;
			} else {
				return isChildren(t, pt.getTadeModule());
			}
		}
		return false;
	}

	public AdeModule get(String id) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("id", id);
		TadeModule t = moduleDao.get("from TadeModule t left join fetch t.tadeModule resource where t.id = :id",
				params);
		AdeModule r = new AdeModule();
		BeanUtils.copyProperties(t, r);
		if (t.getTadeModule() != null) {
			r.setParentModuleId(t.getTadeModule().getId());
			r.setParentModuleName(t.getTadeModule().getModuleName());
		}
		r.setModuleType(t.getModuleType());

		if (StringUtil.isNotEmpty(t.getModuleIcon())) {
			r.setModuleIcon(t.getModuleIcon());
		}
		return r;
	}

	public List<Tree> systemMenuTree(AdeUser user, String moduleGround) {

		List<TadeModule> l = null;
		List<Tree> lt = new ArrayList<Tree>();

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("resourceTypeId", CodeConstant.MODULE_TYPE_MENU);// 菜单类型的"菜单"

		if (user != null) {

			StringBuffer hql = new StringBuffer();
			hql.append(" select distinct t from TadeModule t ");
			hql.append("   join fetch t.tadeRoles role ");
			hql.append("   join role.tadeUsers user ");
			hql.append("  where t.moduleType = :resourceTypeId ");
			hql.append("    and user.id = :userId ");

			// 2017年4月12日：为module增加了维度（暂时定义为前台、后台）
			hql.append("    and t.moduleGround = :moduleGround ");
			hql.append("  order by t.moduleSort");

			params.put("moduleGround", moduleGround);
			params.put("userId", user.getId());// 自查自己有权限的模块
			l = moduleDao.find(hql.toString(), params);
		} else {

			StringBuffer hql = new StringBuffer();
			hql.append(" select distinct t from TadeModule t ");
			hql.append("   where t.moduleType = :resourceTypeId ");
			// 2017年4月12日：为module增加了维度（暂时定义为前台、后台）
			hql.append("     and t.moduleGround = :moduleGround ");
			hql.append("   order by t.moduleSort ");

			params.put("moduleGround", moduleGround);

			l = moduleDao.find(hql.toString(), params);
		}

		IconFontHelper helper = null;
		try {
			helper = IconFontHelper.getInstance();
		} catch (DocumentException e) {
			LOG.error(e.getMessage(), e);
		}

		if (l != null && l.size() > 0) {
			for (TadeModule r : l) {
				Tree easyUITree = new Tree();
				BeanUtils.copyProperties(r, easyUITree);
				if (r.getTadeModule() != null) {
					easyUITree.setPid(r.getTadeModule().getId());
				}
				easyUITree.setText(r.getModuleName());

				if (StringUtil.isNotEmpty(r.getModuleIcon())) {
					easyUITree.setText("<i class=\"iconfont\">" + helper.getUnicode(r.getModuleIcon()) + "</i>&nbsp;"
							+ r.getModuleName());
				}

				Map<String, Object> attr = new HashMap<String, Object>();
				attr.put("url", r.getModuleUrl());
				easyUITree.setAttributes(attr);
				lt.add(easyUITree);
			}
		}

		return lt;
	}

	/**
	 * 列出所有的权限
	 * 
	 * @return 权限地址
	 */
	@Cacheable(value = "adeAllPermissionListCache")
	public List<String> allPermission() {

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("moduleType", CodeConstant.MODULE_TYPE_PERMISSION);// 菜单类型的"菜单"

		String hql = "from TadeModule t where t.moduleType = :moduleType";

		List<TadeModule> permissions = moduleDao.find(hql, params);

		List<String> result = new ArrayList<>();
		for (TadeModule permission : permissions) {
			result.add(permission.getModuleUrl());
		}

		return result;
	}
}
